package ipcards.rulesets;
import ipcards.net.*;
import ipcards.*;
import ipcards.events.PlayerAction;

import java.util.Vector;
import java.util.LinkedList;
import java.lang.Integer;
import javax.swing.JOptionPane;
import java.awt.Point;


public class ThreeUpThreeDownRuleSet extends Ruleset {
	
	//messages
	public static final int SUCCESS = 0;
	public static final int ERR = 1;
	public static final int FACE_DOWN = 2;
	
	private String deckused = "NoJokers.deck";
	private final int DECKSIZE = 52;
	private final int NUMDEALTCARDS = 9;
	private int dealerID = -1;
	public boolean canShuffle = false;
	public boolean canNewGame = false;
	private int[] faceUpChange;
	
	private ThreeUpThreeDownGame game;
	private CardsServer thisserver;
	
	public ThreeUpThreeDownRuleSet(CardsServer s, ThreeUpThreeDownGame g) {
		thisserver = s;
		game = g;
	}
	
	public String getDeckName() {
		return deckused;
	}
	
	public int getDeckSize() {
		return DECKSIZE;
	}
	
	public int getDealerID(){
		return dealerID;
	}
	
	public void setDealerID(int ID){
		dealerID = ID;
	}
	
	public void deal(int players, CardSet thisdeck) {
		CardSet inGameDeck = new CardSet(thisdeck);
		
		faceUpChange = new int[players];				//allow face ups to be changed
		for(int i=0; i<faceUpChange.length;i++){
		 	faceUpChange[i] = 1;
	 	}
		/*dealerID++;
		if(dealerID >= players){
			dealerID = 0;
		}*/
		//Ensure there are enough cards
		/*int tempnumplayers = players.size();
		while((tempnumplayers * NUMDEALTCARDS) >= DECKSIZE)
		{
			Deck d = new Deck(deckused);
			getRoom().getTable().addDeck(d);					///ADD APPROPRIATE DECK -> done in game class as not called every deal
			tempnumplayers -= DECKSIZE;
		}
		deck = getRoom().getTable().getcards();*/
		for(Card c : thisdeck) {
			c.setFaceDown();
			//get to server model to set locallyFlippedCards = new CardSet<Card>();
			c.setLocation(525,450);
		}
				
		thisdeck.shuffle();						///SHUFFLE DECK
		
		for(int i=0; i < players; i++) {
			if(thisserver.clients.get(i) != null) {
				for(int j = 0; j < NUMDEALTCARDS; j++) {
				 	Card c = thisdeck.getCardFromZ(i * NUMDEALTCARDS + j);
				 		///ASSIGN CARDS j TO PLAYER i
				 		System.out.println(i +":" + j);
				 	inGameDeck.remove(c);	
				 	c.addPermission((thisserver.clients.get(i)).thisplayer,thisserver.CONTROL, game.getRoom().getTable().getPlayer());
				 	
				 	switch(j){
					 	
					 					//FACE DOWN CARDS
					 	case 0:	
					 		c.setLocation(new Point((int)(game.getPlayerLocationCircle(i).getX() - 150), (int)(game.getPlayerLocationCircle(i).getY())));
					 		game.addPlayerCard((thisserver.clients.get(i)),c,0); //0 corresponds to face down, 1 to face up and 2 to hand
//SEND TO BACK					 		
					 		break;
					 		
					 	case 1:		
				 			c.setLocation(game.getPlayerLocationCircle(i));
					 		game.addPlayerCard((thisserver.clients.get(i)),c,0);
//SEND TO BACK
				 			break;
				 			
				 		case 2:	
					 		c.setLocation(new Point((int)(game.getPlayerLocationCircle(i).getX() + 150), (int)(game.getPlayerLocationCircle(i).getY())));
					 		game.addPlayerCard((thisserver.clients.get(i)),c,0);
//SEND TO BACK
					 		break;	
				 	
					 					//FACE UP CARDS
					 		
				 		case 3:	
					 		c.setLocation(new Point((int)(game.getPlayerLocationCircle(i).getX() - 150), (int)(game.getPlayerLocationCircle(i).getY())));
					 		game.addPlayerCard((thisserver.clients.get(i)),c,1);
					 		c.setFaceUp();
					 		break;
					 		
					 	case 4:	
					 		c.setLocation(game.getPlayerLocationCircle(i));
					 		game.addPlayerCard((thisserver.clients.get(i)),c,1);
					 		c.setFaceUp();
					 		break;
					 		
					 	case 5:	
					 		c.setLocation(new Point((int)(game.getPlayerLocationCircle(i).getX() + 150), (int)(game.getPlayerLocationCircle(i).getY())));
					 		game.addPlayerCard((thisserver.clients.get(i)),c,1);
					 		c.setFaceUp();
					 		break;
					 		
					 					//HAND
					 					
					 	case 6:	
					 		c.setLocation(new Point((int)(game.getPlayerLocationCircle(i).getX() - 50), (int)(game.getPlayerLocationCircle(i).getY() + 125)));
					 		game.addPlayerCard((thisserver.clients.get(i)),c,2);
				 			c.addPermission((thisserver.clients.get(i)).thisplayer,thisserver.SEE, game.getRoom().getTable().getPlayer());
					 		break;
					 		
					 	case 7:	
					 		c.setLocation(new Point((int)(game.getPlayerLocationCircle(i).getX()), (int)(game.getPlayerLocationCircle(i).getY() + 125)));
					 		game.addPlayerCard((thisserver.clients.get(i)),c,2);
				 			c.addPermission((thisserver.clients.get(i)).thisplayer,thisserver.SEE, game.getRoom().getTable().getPlayer());
					 		break;
					 		
					 	case 8:	
					 		c.setLocation(new Point((int)(game.getPlayerLocationCircle(i).getX() + 50), (int)(game.getPlayerLocationCircle(i).getY() + 125)));
					 		game.addPlayerCard((thisserver.clients.get(i)),c,2);
				 			c.addPermission((thisserver.clients.get(i)).thisplayer,thisserver.SEE, game.getRoom().getTable().getPlayer());
					 		break;
				 	}						
				 	
				 	
			 	}
		 	}
	 	}
	 	
	 	game.deck = inGameDeck;
 	}
 	
 	public int playCards(CardSet cset, Card discardTop, Client playing){
	 	int csetRank = -1;
	 	if(cset.size() == 0){
		 	System.out.println("No cards selected");
		 	return ERR;
	 	}
	 	
	 	for(Card c: cset){
		 	if(csetRank == -1){
			 	csetRank = Integer.parseInt(c.getAttribute("rank"));
		 	}
		 	else if(Integer.parseInt(c.getAttribute("rank")) != csetRank){
			 	//CARDS ARE NOT ALL OF THE SAME RANK....CARD SET IS ILLEGAL AND NOT PLAYABLE
			 	System.out.println("The cards you have chosen to play are not of the same rank. Please choose a card(s) of the same rank");
			 	
			 	return ERR;
		 	}
	 	}
	 	//Cardset is all of the same rank...check whether they are from hand, faceups or facedowns
	
	 	int[] cardPos = new int[cset.size()];
	 	int cardnum = 0;
	 	for(Card c: cset){
	 		cardPos[cardnum] = game.queryPlayerCard(playing, c);
	 		cardnum++;
 		}
 		
 		int num2s = 0;			//cards player is attempting to play
 		int num1s = 0;
 		int num0s = 0;
 		
 		for(int i = 0; i<cardPos.length; i++){
	 		if(cardPos[i] == 0){
		 		num0s++;
	 		}
	 		else if(cardPos[i] == 1){
		 		num1s++;
	 		}
	 		else if(cardPos[i] == 2){
		 		num2s++;
	 		}
	 		else {
		 		System.out.println("Error: Cards chosen are not under this player's control");
		 		return ERR;
	 		}
 		}
 		
 		int[] handSize = game.queryPlayerHand(playing);		//cards actually in players 'hand' (including face ups and downs)
 		
 		if(num2s == 0 && handSize[2] != 0){
	 	//not using any cards in their hand when there are some there
System.out.println("not using any cards in their hand when there are some there");	
	 		return ERR;
 		}
 		if(num2s < handSize[2] && (num1s != 0 || num0s != 0)){	
	 	//not all cards the player is playing are in their hand, yet they are not using all the cards in their hand
System.out.println("not all cards the player is playing are in their hand, yet they are not using all the cards in their hand");	
	 		return ERR;
 		}
	 	//if hand not being used correctly, would have returned by this point
	 	if(num0s > 1){
		//trying to play more than one face down card
System.out.println("trying to play more than one face down card");
		 	return ERR;
	 	}
	 	if(num0s > 0 && (handSize[1] > 0 || handSize[2] > 0)){
		//attempting to play a face down card when faceups or hand havnt been played
System.out.println("attempting to play a face down card when faceups or hand havnt been played");
System.out.println("Hand size is "+handSize[2]+" and consists of the card(s): "+game.getHand(playing).toString());
System.out.println("You have "+handSize[1]+" face up card(s), consisting of the card(s): "+game.getFaceUps(playing).toString());		
			return ERR;
		}

	 	//.....now check legality compared to card at top of discard pile

	 	cardnum = 0;

	 	if(csetRank == 2){
		 	//playing a 2(s)...legal card(s)
	 		
	 		MoveCardsToDiscardPile(cset, playing, cardPos);
	 		
	 		if(fourOfAKindCheck()){	
	 			DoFourOfAKind(playing);
	 			return SUCCESS;
	 		} 
		 	
		 	game.endTurn(playing);
		 	return SUCCESS;
	 	}
	 	
	 	else if(csetRank == 10){
		 	//playing a 10(s)...legal card(s)
	 		MoveCardsToDiscardPile(cset, playing, cardPos);
	 		DoFourOfAKind(playing);
	 		return SUCCESS;	 		 
	 	}
	 	
	 	else if(csetRank == 11){
		 	//playing a Jack(s)...legal card(s)
		 	int csetSize = cset.size();
		 	int reverse = csetSize%2;
		 	fillHand(game.getPreviousPlaying(playing));
			//update clients
			playing.getServerModel().sync();
			
			MoveCardsToDiscardPile(cset, playing, cardPos);
			
			if(fourOfAKindCheck()){	
	 			DoFourOfAKind(playing);
	 			return SUCCESS;
	 		} 
		 	
		 	if(game.numPlayersIn() == 2){
			 	//2 players left....play again
			 	game.unsetFillHand();
			 	return SUCCESS;
		 	}
		 	else{
			 	if(reverse == 1){
			 		game.reverseDirection();
		 		}
			 	game.endTurn(playing);
			 	return SUCCESS;
		 	}
	 	}
	 	else if(discardTop == null){
		 	//legal card(s) as no cards in discard pile
	 		
	 		MoveCardsToDiscardPile(cset, playing, cardPos);
	 		
	 		if(fourOfAKindCheck()){	
	 			DoFourOfAKind(playing);
	 			return SUCCESS;
	 		} 
	 		
		 	game.endTurn(playing);
		 	return SUCCESS;
	 	}
	 	else if(csetRank >= Integer.parseInt(discardTop.getAttribute("rank")) || csetRank == 13){

		 	//legal card(s)
	 		MoveCardsToDiscardPile(cset, playing, cardPos);
	 		
	 		if(fourOfAKindCheck()){	
	 			DoFourOfAKind(playing);
	 			return SUCCESS;
	 		}
	 		
		 	game.endTurn(playing);
		 	return SUCCESS;
	 	}
	 	else if(num0s == 1){
		 	//illegal card turned as a face down card....add card to hand and pick up deck		 	
		 	Card turned = null;			//initilise card object for face down card that was turned over
		 	CardSet play = new CardSet();
		 	for(Card c: cset){
			 	turned = c;
			 	play.add(c);
		 	 }
		 	 
		 	turned.setFaceUp(); 
		 	game.getRoom().table.sModel.performPlayerAction(new PlayerAction(game.getRoom().table.sModel, PlayerAction.SET_FACE_UP, play.toString()));
		 	game.addPlayerCard(playing, turned, 2);
		 	game.removePlayerCard(playing, turned, 0);
		 	turned.addPermission(playing.thisplayer,thisserver.CONTROL, game.getRoom().getTable().getPlayer());
		 	turned.addPermission(playing.thisplayer,thisserver.SEE, game.getRoom().getTable().getPlayer());
		 	//card added to hand
		 	try{
				Thread.sleep(2000);
			}
			catch(InterruptedException e){
			}
			turned.setFaceDown();
		 	game.pickUpDeck(playing);
		 	System.out.println("The face down card played is not legal in the current situation. You are picking up the deck");
		 	return FACE_DOWN;
	 	}
	 	System.out.println("The card(s) you are playing are not legal in the current situation. Please either choose other cards or pick up the deck");
	 	return ERR;
 	}
 	
 	private void MoveCardsToDiscardPile(CardSet cset, Client playing, int[] cardPos) {
 		int cardnum = 0;
 		
 		for(Card c: cset){
		 	game.discards.add(c);
		 	game.discardTop = c;
		 	layOutDiscardTops();
		 	c.setFaceUp();
			game.resetLocalFlip(c);	
		 	c.removePermission(playing.thisplayer,thisserver.CONTROL, game.getRoom().getTable().getPlayer());
		 	c.removePermission(playing.thisplayer,thisserver.SEE, game.getRoom().getTable().getPlayer());
		 	game.removePlayerCard(playing, c, cardPos[cardnum]);
		 	cardnum++;
	 	}
 	}
 	
 	private void DoFourOfAKind(Client playing) {
	 	//update clients
		playing.getServerModel().sync();
 		try {
			Thread.sleep(2000);
		} catch(InterruptedException e){}
		
	 	game.clearDiscards();
	 	game.querySetPlayerOut(playing);
 		int clientnum = -10;
		int count = 0;
		
		for(Client client2: thisserver.clients){
 			if(client2 == playing){		//found current client - set number
 				clientnum = count;
			}
			count++;
		}
		
		//player has gone out on a 10
		if(game.queryIsPlayerOut(clientnum)){		
			game.reverseDirection();
			game.endTurn(playing);
			game.reverseDirection();
		}
 	}
 	
 	public void pickUpDeck(Client playing){	 	
		CardSet addToHand = new CardSet(game.discards);
		game.clearDiscards();
		for(Card c: addToHand){
			game.addPlayerCard(playing, c, 2);
			c.addPermission(playing.thisplayer,thisserver.CONTROL, game.getRoom().getTable().getPlayer());
			c.addPermission(playing.thisplayer,thisserver.SEE, game.getRoom().getTable().getPlayer());
			c.setFaceDown();
		}
		
		layoutHand(game.getHand(playing),playing);	 	
 	}
 	
 	private boolean fourOfAKindCheck(){
	 	if(game.discards.size() < 4){
		 	return false;
	 	}
	 	
	 	int[] top4 = new int[4];
	 	Card c = game.discards.elementAt(game.discards.size()-1);
	 	top4[0] = Integer.parseInt(c.getAttribute("rank"));
	 	c = game.discards.elementAt(game.discards.size()-2);
	 	top4[1] = Integer.parseInt(c.getAttribute("rank"));
	 	c = game.discards.elementAt(game.discards.size()-3);
	 	top4[2] = Integer.parseInt(c.getAttribute("rank"));
	 	c = game.discards.elementAt(game.discards.size()-4);
	 	top4[3] = Integer.parseInt(c.getAttribute("rank"));
	 	
	 	if(top4[0] == top4[1] && top4[0] == top4[2] && top4[0] == top4[3]){
		 	return true;
	 	}
	 	return false;
 	}
 	
 	public void fillHand(Client previous){
	 	int[] handSize = game.queryPlayerHand(previous);
int x=0;	 	
for(Client c: game.getRoom().controller.getServer().clients){
	if(c == previous){
			 	
//System.out.println("fill hand " + x + ": hand size is " + handSize[2]);
	}
	else{
		x++;
	}
}
	 	if(game.deck.size() != 0 && handSize[2] < 3){
//System.out.println("if clause passed");
		 	while(game.deck.size() > 0){
			 	
//System.out.println("while clause looped");
			 	//Card toAdd = null;
			 	//for(Card c: game.deck){
				// 	toAdd = c;
				// 	break;
			 	//}
			 	game.deck.shuffle();
			 	Card toAdd = game.deck.getCardFromZ(0);
			 	
			 	game.deck.remove(toAdd);
			 	game.addPlayerCard(previous, toAdd, 2);
				toAdd.addPermission(previous.thisplayer,thisserver.CONTROL, game.getRoom().getTable().getPlayer());
				toAdd.addPermission(previous.thisplayer,thisserver.SEE, game.getRoom().getTable().getPlayer());
//System.out.println("trying to fill hand");				
				handSize = game.queryPlayerHand(previous);
//				System.out.println("hand size "+ handSize[2]);
				if(handSize[2] == 3){
					//hand is full
//					System.out.println("full hand");
					layoutHand(game.getHand(previous),previous);
					return;
				}
			}
		}
	}
 	
 	public void layoutHand(CardSet hand, Client player){
	 	//Future developments here could include sorting by suit, number, number then suit (or visa versa), other sorting types, and randomising 
	 	LinkedList<Card> zorder = game.getRoom().table.cards.ZValueOrder;	 	
	 	int pnum = game.getPlayerNum(player);
	 	int offcentre = 0;
	 	switch(hand.size()){
		 	case 0:
System.out.println("laying out hand of 0 cards");
		 	break;
		 		
		 	case 1:
		 		for(Card c: hand){
			 		c.setLocation(new Point((int)(game.getPlayerLocationCircle(pnum).getX()), (int)(game.getPlayerLocationCircle(pnum).getY() + 125)));
			 		zorder.remove(c);
					zorder.add(c);
		 		}
System.out.println("laying out hand of 1 cards");
		 	break;
		 		
		 	case 2:
		 		offcentre = -25;
		 		for(Card c: hand){
			 		c.setLocation(new Point((int)(game.getPlayerLocationCircle(pnum).getX()+offcentre), (int)(game.getPlayerLocationCircle(pnum).getY() + 125)));
			 		zorder.remove(c);
					zorder.add(c);
			 		offcentre += 50;
//table.drawingList.addLast(c);			 		
		 		}
System.out.println("laying out hand of 2 cards");
		 	break;	
		 			
		 	case 3:
		 		offcentre = -50;
		 		for(Card c: hand){
			 		c.setLocation(new Point((int)(game.getPlayerLocationCircle(pnum).getX()+offcentre), (int)(game.getPlayerLocationCircle(pnum).getY() + 125)));
			 		zorder.remove(c);
					zorder.add(c);
			 		offcentre += 50;
		 		}
//System.out.println("laying out hand of 3 cards");		 		
		 	break;	
		 			
		 	case 4:
		 		offcentre = -75;
		 		for(Card c: hand){
			 		c.setLocation(new Point((int)(game.getPlayerLocationCircle(pnum).getX()+offcentre), (int)(game.getPlayerLocationCircle(pnum).getY() + 125)));
			 		zorder.remove(c);
					zorder.add(c);
			 		offcentre += 50;
		 		}
		 	break;	
		 			
		 	case 5:
		 		offcentre = -100;
		 		for(Card c: hand){
			 		c.setLocation(new Point((int)(game.getPlayerLocationCircle(pnum).getX()+offcentre), (int)(game.getPlayerLocationCircle(pnum).getY() + 125)));
			 		zorder.remove(c);
					zorder.add(c);
			 		offcentre += 50;
		 		}
		 	break;	
		 			
		 	case 6:
		 		offcentre = -125;
		 		for(Card c: hand){
			 		c.setLocation(new Point((int)(game.getPlayerLocationCircle(pnum).getX()+offcentre), (int)(game.getPlayerLocationCircle(pnum).getY() + 125)));
			 		zorder.remove(c);
					zorder.add(c);
			 		offcentre += 50;
		 		}
		 	break;	
		 		
		 	default:
		 		double offcentre2 = -150;
		 		double division = -((2*offcentre2)/(hand.size()-1));
		 		for(Card c: hand){
			 		c.setLocation(new Point((int)(game.getPlayerLocationCircle(pnum).getX()+offcentre2), (int)(game.getPlayerLocationCircle(pnum).getY() + 125)));
			 		zorder.remove(c);
					zorder.add(c);
			 		offcentre2 += division;
		 		}
		 	break;	
	 	}
 	}

//NEED SOMETHING TO HANDLE THE SWAPPING OF CARDS IN HAND WITH FACE UPS BEFORE THE FIRST TURN ---DONE!!!	 	
 	public int setStartFaceUps(Client client,CardSet newfaceups){
	 	int clientnum = -10;
	 	int count = 0;
	 	for(Client client2: thisserver.clients){
		 	if(client2 == client){		//found current client - set number
		 		clientnum = count;
	 		}
	 		count++;
 		}
 		
 		if(faceUpChange[clientnum] == 1){			//player still has rights to swap cards
 			if(newfaceups.size() != 3){
	 			return 2;							//2: incorrect number of cards chosen for face ups (should be 3 cards)
 			}
 		
 			CardSet hand = game.getHand(client);
 			CardSet faceUps = game.getFaceUps(client);
 			
 			CardSet handPlusFUs = hand;		//set of cards encapsulating players hand and face up cards
 			for(Card c: faceUps){
	 			handPlusFUs.add(c);
 			}
 			
 			for(Card c: newfaceups){				//prevents player from setting a card as their face up if it is not already either in their hand or face up set
	 			if(!(handPlusFUs.contains(c))){
		 			return 1;						//1: one or more cards is not valid to be this players face up card as it is either not under their control or is a face down card
	 			}
 			}
 			
 			CardSet newhand = new CardSet();
 			for(Card c: handPlusFUs){
	 			if(!(newfaceups.contains(c))){			//not a new face up card, therefore to go in the player's hand
 					newhand.add(c);
//System.out.println("Debug:14"); 					
				}
//System.out.println("Debug:13");				
			}
			
//System.out.println("Debug:0");	  			
 			//isolate new hand (newfaceups already exists for face up cards), remove ALL permissions and allocations (game.removePlayerCard(...)) for ALL cards in handPlusFUs
 			int[] cardTypes = new int[6];
 			int i=0;
 			Card first = null;
 			Card second = null;
 			Card third = null;
 			Card fourth = null;
 			Card fifth = null;
 			Card sixth = null;
 			for(Card c: handPlusFUs){
	 			cardTypes[i] = game.queryPlayerCard(client, c);
	 			switch(i) {
		 			
		 			case 0:
		 				first = c;
		 			break;
		 			case 1:
		 				second = c;
		 			break;
		 			case 2:
		 				third = c;
		 			break;
		 			case 3:
		 				fourth = c;
		 			break;
		 			case 4:
		 				fifth = c;
		 			break;
		 			case 5:
		 				sixth = c;
		 			break;
	 			}
	 			i++;
 			}
 			i=0;
//System.out.println(handPlusFUs.size()); 			
//System.out.println("Debug:1"); 			
 			for(Card c: handPlusFUs){
//System.out.println("Debug:2");	 			
	 			c.setFaceDown();			
//System.out.println("Debug:3");					 	 			
	 			//game.removePlayerCard(thisserver.clients.get(clientnum), c, cardTypes[i]);
//System.out.println("Debug:4");	 
	 			c.removePermission((thisserver.clients.get(clientnum)).thisplayer,thisserver.CONTROL, game.getRoom().getTable().getPlayer());
//System.out.println("Debug:5");	 
	 			c.removePermission((thisserver.clients.get(clientnum)).thisplayer,thisserver.SEE, game.getRoom().getTable().getPlayer());
//System.out.println("Debug:6");
				i++;	  	
//System.out.println("Debug:7");
//System.out.println(handPlusFUs.size()); 							
	 		}
//System.out.println("Debug:8");
			game.removePlayerCard(thisserver.clients.get(clientnum), first, 2);
			game.removePlayerCard(thisserver.clients.get(clientnum), second, 2);
			game.removePlayerCard(thisserver.clients.get(clientnum), third, 2);
			game.removePlayerCard(thisserver.clients.get(clientnum), fourth, 2);	 	 		
			game.removePlayerCard(thisserver.clients.get(clientnum), fifth, 2);
			game.removePlayerCard(thisserver.clients.get(clientnum), sixth, 2);
//System.out.println("Debug:9");
			game.removePlayerCard(thisserver.clients.get(clientnum), first, 1);
			game.removePlayerCard(thisserver.clients.get(clientnum), second, 1);
			game.removePlayerCard(thisserver.clients.get(clientnum), third, 1);
			game.removePlayerCard(thisserver.clients.get(clientnum), fourth, 1);	 	 		
			game.removePlayerCard(thisserver.clients.get(clientnum), fifth, 1);
			game.removePlayerCard(thisserver.clients.get(clientnum), sixth, 1);

//System.out.println(handPlusFUs.size()); 
 			
			/*CardSet newhand = new CardSet();
 			for(Card c: handPlusFUs){
	 			if(!(newfaceups.contains(c))){			//not a new face up card, therefore to go in the player's hand
 					newhand.add(c);
System.out.println("Debug:14"); 					
				}
System.out.println("Debug:13");				
			}*/
//System.out.println(handPlusFUs.size()); 
 			
 			//lay out face ups
 			int cardnum = 0;
 			for(Card c: newfaceups){	
				c.addPermission((thisserver.clients.get(clientnum)).thisplayer,thisserver.CONTROL, game.getRoom().getTable().getPlayer());
 				
				switch(cardnum){
				
					case 0:	
						c.setLocation(new Point((int)(game.getPlayerLocationCircle(clientnum).getX() - 150), (int)(game.getPlayerLocationCircle(clientnum).getY())));
						game.addPlayerCard((thisserver.clients.get(clientnum)),c,1);
						c.setFaceUp();
					break;
						 		
					case 1:	
						c.setLocation(game.getPlayerLocationCircle(clientnum));
						game.addPlayerCard((thisserver.clients.get(clientnum)),c,1);
						c.setFaceUp();
					break;
						 		
					case 2:	
						c.setLocation(new Point((int)(game.getPlayerLocationCircle(clientnum).getX() + 150), (int)(game.getPlayerLocationCircle(clientnum).getY())));
						game.addPlayerCard((thisserver.clients.get(clientnum)),c,1);
						c.setFaceUp();
					break;
				}
				
				cardnum++;
			}
//System.out.println("Debug:10");
					 	
 			//lay out hand
 			for(Card c: newhand){
 				c.addPermission((thisserver.clients.get(clientnum)).thisplayer,thisserver.CONTROL, game.getRoom().getTable().getPlayer());
 				c.addPermission((thisserver.clients.get(clientnum)).thisplayer,thisserver.SEE, game.getRoom().getTable().getPlayer());	
				game.addPlayerCard((thisserver.clients.get(clientnum)),c,2);
//System.out.println("Debug:11");
			}
			 		
			layoutHand(newhand,client);
//System.out.println("Debug:12");
			 
 			return 0;
		}
		else{
			return 3;			//3: play has already started, so face ups cannot be swapped any more (for this player)
		}
 	}
 	
 	public void setEndFaceUpChange(Client justPlayed){
	 	int clientnum = -10;
	 	int count = 0;
	 	for(Client client: thisserver.clients){
		 	if(client == justPlayed){		//found current client - set number
		 		clientnum = count;
	 		}
	 		count++;
 		}
	 	
 		faceUpChange[clientnum] = 0;					//0 implies no changes can be made. 1 implies can change face ups
	 	
 	}
 	
 	private void layOutDiscardTops(){
	 	int number2display = 0;
	 	int[] top4 = new int[4];
	 	Card c = null;
	 	Card c2 = null;
	 	Card c3 = null;
	 	Card c4 = null;
	 	if(game.discards.size() == 0){
		 	return;
	 	}
	 	else if(game.discards.size() == 1){
		 	c = game.discards.elementAt(game.discards.size()-1);
		 	number2display = 1;
	 	}
	 	else if(game.discards.size() == 2){
	 		c = game.discards.elementAt(game.discards.size()-1);
	 		c2 = game.discards.elementAt(game.discards.size()-2);
	 		top4[0] = Integer.parseInt(c.getAttribute("rank"));
	 		top4[1] = Integer.parseInt(c2.getAttribute("rank"));
	 		if(top4[0] == top4[1]){
		 		number2display = 2;
	 		}
	 		else{
		 		number2display = 1;
	 		}
	 	}
	 	else if(game.discards.size() == 3){
	 		c = game.discards.elementAt(game.discards.size()-1);
	 		c2 = game.discards.elementAt(game.discards.size()-2);
	 		c3 = game.discards.elementAt(game.discards.size()-3);
	 		top4[0] = Integer.parseInt(c.getAttribute("rank"));
	 		top4[1] = Integer.parseInt(c2.getAttribute("rank"));
	 		top4[2] = Integer.parseInt(c3.getAttribute("rank"));
	 		if(top4[0] == top4[1] && top4[0] == top4[2]){
		 		number2display = 3;
	 		}
	 		else if(top4[0] == top4[1]){
		 		number2display = 2;
	 		}
	 		else{
		 		number2display = 1;
	 		}
	 	}
	 	else{
	 		c = game.discards.elementAt(game.discards.size()-1);
	 		c2 = game.discards.elementAt(game.discards.size()-2);
	 		c3 = game.discards.elementAt(game.discards.size()-3);
	 		c4 = game.discards.elementAt(game.discards.size()-4);
		 	top4[0] = Integer.parseInt(c.getAttribute("rank"));
	 		top4[1] = Integer.parseInt(c2.getAttribute("rank"));
	 		top4[2] = Integer.parseInt(c3.getAttribute("rank"));
	 		top4[3] = Integer.parseInt(c4.getAttribute("rank"));
	 		if(top4[0] == top4[1] && top4[0] == top4[2] && top4[0] == top4[3]){
		 		number2display = 4;
	 		}
	 		else if(top4[0] == top4[1] && top4[0] == top4[2]){
		 		number2display = 3;
	 		}
	 		else if(top4[0] == top4[1]){
		 		number2display = 2;
	 		}
	 		else{
		 		number2display = 1;
	 		}
	 	}
	 	
	 	//set zordering and positions
	 	//LinkedList<Card> zorder = client.getServerModel().table.cards.ZValueOrder;		//need to define client--passed into method
		LinkedList<Card> zorder = game.getRoom().table.cards.ZValueOrder;
 		
 		if(number2display == 4){
//System.out.print("L to R: " + c4.getImmutableID() + "," + c3.getImmutableID() + "," + c2.getImmutableID() + "," + c.getImmutableID() + "\n");	 		
	 		c4.setLocation(360,450);
			zorder.remove(c4);
			zorder.add(c4);
	 		c3.setLocation(370,450);
			zorder.remove(c3);
			zorder.add(c3);
	 		c2.setLocation(380,450);
			zorder.remove(c2);
			zorder.add(c2);
	 		c.setLocation(390,450);
			zorder.remove(c);
			zorder.add(c);
 		}
 		else if(number2display == 3){
	 		if(c4 != null){
		 		c4.setLocation(375,450);
	 		}
//System.out.print("L to R: "+ c3.getImmutableID() + "," + c2.getImmutableID() + "," + c.getImmutableID() + "\n");		 		
	 		c3.setLocation(365,450);
			zorder.remove(c3);
			zorder.add(c3);
	 		c2.setLocation(375,450);
			zorder.remove(c2);
			zorder.add(c2);
	 		c.setLocation(385,450);
			zorder.remove(c);
			zorder.add(c);
 		}
 		else if(number2display == 2){
	 		if(c4 != null){
		 		c4.setLocation(375,450);
	 		}
	 		if(c3 != null){
		 		c3.setLocation(375,450);
	 		}
//System.out.print("L to R: " + c2.getImmutableID() + "," + c.getImmutableID() + "\n");		 		
	 		c2.setLocation(370,450);
			zorder.remove(c2);
			zorder.add(c2);
	 		c.setLocation(380,450);
			zorder.remove(c);
			zorder.add(c);
 		}
 		else{
	 		if(c4 != null){
		 		c4.setLocation(375,450);
	 		}
	 		if(c3 != null){
		 		c3.setLocation(375,450);
	 		}
	 		if(c2 != null){
		 		c2.setLocation(375,450);
	 		}
	 		c.setLocation(375,450);
 		}
 	}
 	
 	public void changePermissions(int changeTo, Card c, Client current){			//0 = remove, 1 = add
 	 	c.removePermission(current.thisplayer,thisserver.CONTROL, game.getRoom().getTable().getPlayer());
		c.removePermission(current.thisplayer,thisserver.SEE, game.getRoom().getTable().getPlayer());
	}

}